using System;
using System.Collections;
using SQLDMO;
using SQLServices.Repository;

namespace SQLRunnerDMO
{
	/// <summary>
	/// Simplified version of a SQL Server DMO object
	/// </summary>
	public sealed class SQLConnection : ISQLConnection, IDisposable
	{

		#region Private Instances

		private SQLServer2 _sqlServer;
		private bool _loginSecure;
		private string _serverName;
		private string _userId;
		private string _password;
		private SQLDatabase _database;

		#endregion

		#region Properties
		
		public bool LoginSecure
		{
			get { return _loginSecure; }
		}

		public string ServerName
		{
			get { return _serverName; }
		}

		public string UserId
		{
			get { return _userId; }
		}

		public string Password
		{
			get { return _password; }
		}

		public int VersionMajor
		{
			get { return _sqlServer.VersionMajor; }
		}
		#endregion
		#region Public Methods

		public void OpenConnection(string serverName, string userId, string password, bool trusted)
		{
			Reset();
			_sqlServer.LoginSecure = trusted;
			_loginSecure = trusted;
			_sqlServer.ApplicationName = "SQLRunner";
			_sqlServer.Connect(serverName, userId, password);
			_serverName = serverName;
			_userId = userId;
			_password = password;
		}

		public ISQLDBConn GetDatabase(string databaseName)
		{
			if ( _sqlServer == null ) 
				throw new ApplicationException("Connection to the SQL Server was " + 
					"not established, please call the 'OpenConnection' method " + 
					"before this method is executed");
			if ( _database != null && _database.DatabaseName.Equals(databaseName)) return _database;
			_database = new SQLDatabase(this, databaseName);
			return _database;
		}

		public ISQLDBConn GetDatabase()
		{
			if ( _database != null ) return _database;
			throw new ApplicationException("Internal database has not been initialise, " +
				"please use the overloaded method indicating the database name to retrieve");
		}

		public void Reset()
		{
			Disconnect();
			_sqlServer = new SQLServer2Class();
		}

		public void Disconnect()
		{
			if (_sqlServer != null)
			{
				_sqlServer.DisConnect();
				_sqlServer.Close();
			    _sqlServer = null;
			}
		}

		internal _Database Database(string databaseName)
		{
			_Database dmoDatabase;
			if (_sqlServer.Status == SQLDMO_SVCSTATUS_TYPE.SQLDMOSvc_Running)
			{
				dmoDatabase = _sqlServer.Databases.Item(databaseName, _sqlServer.Databases);
			}
			else 
			{
				throw new InvalidOperationException("SQL Server is not available");
			}
			return dmoDatabase;
		}

		public ArrayList ListOfDatabases()
		{
			if ( _sqlServer == null ) return null;
			ArrayList list = new ArrayList(_sqlServer.Databases.Count);
			foreach (Database2 database in _sqlServer.Databases)
			{	
				list.Add(database.Name); 
			}
			return list;
		}
		#endregion

		#region IDisposable Members

		public void Dispose()
		{
			if ( _sqlServer != null && 
				_sqlServer.Status == SQLDMO_SVCSTATUS_TYPE.SQLDMOSvc_Running )
			{
				_sqlServer.DisConnect();
				_sqlServer.Close();
				_sqlServer = null;
				
			}
		}

		#endregion
	}
}
